package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.google.common.collect.Lists;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.DeptDto;
import com.zzyl.entity.Dept;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeptMapper;
import com.zzyl.mapper.PostMapper;
import com.zzyl.service.DeptService;
import com.zzyl.service.UserService;
import com.zzyl.utils.BeanConv;
import com.zzyl.utils.EmptyUtil;
import com.zzyl.utils.NoProcessing;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.vo.DeptVo;
import com.zzyl.vo.TreeItemVo;
import com.zzyl.vo.TreeVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 部门表服务实现类
 */
@Service
@Slf4j
public class DeptServiceImpl implements DeptService {

    @Autowired
    DeptMapper deptMapper;

    @Resource
    private PostMapper postMapper;

    @Autowired
    private UserService userService;


    /**
     * 部门表添加
     * @param deptDto 对象信息
     * @return
     */
    @Override
    public Boolean createDept(DeptDto deptDto) {
        String parentDeptNo = deptDto.getParentDeptNo();
        // 校验父部门编号是否是五级，五级部门为最低级，不能做父部门
        String targetString = parentDeptNo.substring(parentDeptNo.length() - 3);
        if (!Objects.equals("000", targetString)) {
            throw new BaseException("部门最多4级");
        }

        //获取父部门下的所有部门
        List<Dept> deptList = deptMapper.selectList(deptDto);

        // 删除父编号后面的000
        int step = 0;
        while (Objects.equals("000", targetString)) {
            parentDeptNo = parentDeptNo.substring(0, parentDeptNo.length() - 3);
            targetString = parentDeptNo.substring(parentDeptNo.length() - 3);
            step ++;
        }

        StringBuilder deptNo = new StringBuilder(parentDeptNo);
        if (Objects.requireNonNullElse(deptList, Collections.emptyList()).isEmpty()) {
            // 说明父部门下无子部门
            deptNo.append("001");
        } else {
            // 父部门下的最大部门加一
            deptNo.append(String.format("%03d", deptList.size() + 1 ));
        }

        // 补全剩余编码
        while (step > 1) {
            deptNo.append("000");
            step --;
        }
        log.info("生成的部门编码为：{}", deptNo);

        Dept dept = BeanUtil.toBean(deptDto, Dept.class);
        dept.setDeptNo(deptNo.toString());
        int insert = deptMapper.insert(dept);
        if (insert != 1) {
            throw new BaseException("部门添加失败");
        }

        //如果当前leader也是其他其他部门的负责人，则清空其他部门的leader数据
        //一个人只能是一个部门的leader
        if (ObjectUtil.isNotEmpty(deptDto.getLeaderId())) {
            //根据leader查询，如果存在，则清空
            deptMapper.clearOtherDeptLeader(deptDto.getLeaderId(), deptNo.toString());
            //在用户表设置标识，表明当前部门的leader
            userService.updateIsLeaderByUserIdAndDeptNo(deptDto.getLeaderId(), dept.getDeptNo());
        }

        return true;
    }


    @Override
    public Boolean updateDept(DeptDto deptDto) {
        //转换DeptVo为Dept
        Dept dept = BeanUtil.toBean(deptDto, Dept.class);

        //检验是否可以修改
        if (dept.getDataState().equals("1")) {
            if (hasChildByDeptId(dept.getDeptNo())) {
                throw new RuntimeException("存在下级部门,不允许禁用");
            }
            if (checkDeptExistUser(dept.getDeptNo())) {
                throw new RuntimeException("部门存在用户,不允许禁用");
            }
        }

        //修改
        int flag = deptMapper.updateByPrimaryKey(dept);
        if (flag == 0) {
            throw new RuntimeException("修改部门信息出错");
        }

        //如果当前leader也是其他其他部门的负责人，则清空其他部门的leader数据
        //一个人只能是一个部门的leader
        if (ObjectUtil.isNotEmpty(deptDto.getLeaderId())) {
            //根据leader查询，如果存在，则清空
            deptMapper.clearOtherDeptLeader(deptDto.getLeaderId(), deptDto.getDeptNo());
            //在用户表设置标识，表明当前部门的leader
            userService.updateIsLeaderByUserIdAndDeptNo(deptDto.getLeaderId(), dept.getDeptNo());
        }

        return true;
    }


    /**
     * 是否存在子节点
     *
     * @param deptId 部门ID
     * @return 结果
     */
    public boolean hasChildByDeptId(String deptId) {
        int result = deptMapper.hasChildByDeptId(deptId);
        return result > 0 ? true : false;
    }

    /**
     * 查询部门是否存在用户
     *
     * @param deptId 部门ID
     * @return 结果 true 存在 false 不存在
     */
    public boolean checkDeptExistUser(String deptId) {
        int result = deptMapper.checkDeptExistUser(deptId);
        return result > 0 ? true : false;
    }


    @Override
    public List<DeptVo> findDeptList(DeptDto deptDto) {
        List<Dept> deptList = deptMapper.selectList(deptDto);
        List<DeptVo> deptVos = BeanConv.toBeanList(deptList, DeptVo.class);
        deptVos.forEach(v -> v.setCreateDay(LocalDateTimeUtil.format(v.getCreateTime(), "yyyy-MM-dd")));
        return deptVos;
    }

    @Override
    public List<DeptVo> findDeptInDeptNos(List<String> deptNos) {
        return List.of();
    }

    @Override
    public String createDeptNo(String parentDeptNo) {
        return "";
    }

    @Override
    public List<DeptVo> findDeptVoListInRoleId(List<Long> roleIds) {
        return List.of();
    }

    @Override
    public int deleteDeptById(String deptId) {
        if (hasChildByDeptId(deptId)) {
            throw new RuntimeException("存在下级部门,不允许删除");
        }
        if (checkDeptExistUser(deptId)) {
            throw new RuntimeException("部门存在用户,不允许删除");
        }

        postMapper.deletePostByDeptNo(deptId);
        return deptMapper.deleteByDeptNo(deptId);
    }

    @Override
    public Boolean isEnable(DeptDto deptDto) {
        //查询部门
        Dept dept = deptMapper.selectByDeptNo(deptDto.getDeptNo());
        if (dept == null) {
            throw new BaseException("部门不存在");
        }
        //设置状态
        dept.setDataState(deptDto.getDataState());
        //修改
        int count = deptMapper.updateByPrimaryKey(dept);
        if (count == 0) {
            throw new RuntimeException("修改部门信息出错");
        }
        return true;
    }

    @Override
    public TreeVo deptTreeVo() {
        //根节点查询树形结构
        String parentDeptNo = SuperConstant.ROOT_DEPT_PARENT_ID;
        DeptDto deptDto = DeptDto.builder()
                .dataState(SuperConstant.DATA_STATE_0)
                .parentDeptNo(NoProcessing.processString(parentDeptNo))
                .build();
        //查询部门列表数据
        List<Dept> deptList =  deptMapper.selectList(deptDto);
        if (EmptyUtil.isNullOrEmpty(deptList)){
            throw new BaseException("部门数据为空");
        }

        List<TreeItemVo> treeItemVoList = new ArrayList<>();
        Dept deptRoot = deptList.stream().filter(dept -> dept.getParentDeptNo().equals(parentDeptNo))
            .collect(Collectors.toList()).get(0);

        recursionTreeItem(treeItemVoList, deptRoot, deptList);

        //返回
        return TreeVo.builder()
            .items(treeItemVoList)
            .build();
    }




    /**
     * 构建树形结构，递归调用
     * @param treeItemVoList   封装返回的对象
     * @param deptRoot  当前部门
     * @param deptList  部门列表（全部数据）
     */
    private void recursionTreeItem(List<TreeItemVo> treeItemVoList, Dept deptRoot, List<Dept> deptList) {
        TreeItemVo itemVo = TreeItemVo.builder()
            .id(deptRoot.getDeptNo())
            .label(deptRoot.getDeptName())
            .build();

        // 获取当前父节点的下的子节点
        List<Dept> childrenDept = deptList.stream().filter(dept -> dept.getParentDeptNo().equals(deptRoot.getDeptNo()))
            .collect(Collectors.toList());

        if (!EmptyUtil.isNullOrEmpty(childrenDept)) {
            //子部门列表
            List<TreeItemVo> listChildren = Lists.newArrayList();
            childrenDept.forEach(dept -> {
                recursionTreeItem(listChildren, dept, deptList);
            });
            itemVo.setChildren(listChildren);
        }

        treeItemVoList.add(itemVo);
    }




}
